package sy.util.ref;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import sy.pageModel.User;

 

@SuppressWarnings({"unchecked","rawtypes"})
public class MyBeanUtils {
/**
 *call javabean`s getter method,return object   
 * @param propertyName
 * @param obj
 * @return
 */
	public static Object callGetterMethod(String propertyName,Object obj){

		PropertyDescriptor pd;
		try {
			propertyName=getSupperProperty(propertyName,obj.getClass());
			pd = new PropertyDescriptor(propertyName,obj.getClass());
			Method methodGet = pd.getReadMethod();
			Object reValue = methodGet.invoke(obj);
			return reValue;
		} catch (IntrospectionException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	public static void callSetterMethod(String propertyName,Object value,Object obj){
		PropertyDescriptor pd;
		try {
			propertyName=getSupperProperty(propertyName,obj.getClass());
			pd = new PropertyDescriptor(propertyName,obj.getClass());
			Method methodSet = pd.getWriteMethod();
		    methodSet.invoke(obj,value);
		}catch (IntrospectionException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
	}
	public static Object callAnyMethod(String method,Object obj,Class<Object>[] clazz, Object[] args) 
			throws Exception{
		Method m=obj.getClass().getMethod(method, clazz);
		Object result=m.invoke(obj, args);
		return result;
	}
	

	public static Map<String,Object> getPropertiesMap(Object obj){
		Map<String, Object> map=new HashMap();
		Field []properties=obj.getClass().getDeclaredFields();
		for(int i=0;i<properties.length;i++){
			String property=properties[i].getName();
			Object value=callGetterMethod(property,obj);
			map.put(property, value);
		}
		return  map;
	}
	public static Map<String,Object>getAllPropertiesMap(Object obj){
	
		Map<String, Object> map=new HashMap();
		Field []properties=obj.getClass().getDeclaredFields();
		for(int i=0;i<properties.length;i++){
			String property=properties[i].getName();
			Object value=callGetterMethod(property,obj);
			map.put(property, value);
		}
		Field []supperProperties=obj.getClass().getSuperclass().getDeclaredFields();
		for(int i=0;i<supperProperties.length;i++){
			String property=supperProperties[i].getName();
			Object value=callGetterMethod(property,obj);
			map.put(property, value);
		}
		return map;
	}
	public static Object setBean(Map<String,Object> map,Object obj){
		Set<String> keyset=map.keySet();
		for(String pro:keyset){
			Object value=map.get(pro);
			if(value!=null)
			   callSetterMethod(pro,value,obj);
		}
		return obj;
	}
	public static List<String> getPropertiesList(Class<?> clazz){
		List<String> list=new ArrayList();
		Field[] field=clazz.getDeclaredFields();
		for(int i=0;i<list.size();i++){
			list.add(field[i].getName());
		}
		return list;
	}
	public static List<String> getAllProperties(Class<?> clazz){
		List<String> list=new ArrayList<String>();
		Field[] field=clazz.getDeclaredFields();
		for(int i=0;i<list.size();i++){
			list.add(field[i].getName());
		}
		field=clazz.getSuperclass().getDeclaredFields();
		for(int i=0;i<list.size();i++){
			list.add(field[i].getName());
		}
		return list;
	}
	public static Map<String,Class<?>> getPropertyTypesMap(Class<?> clazz){
		return null;
	}
	/**
	 * find the really property according to  str that ignore  case
	 * @param str
	 * @return
	 */
	public static String getProperty(String str,Class<?> clazz){
		Field []properties=clazz.getDeclaredFields();
		for(int i=0;i<properties.length;i++){
			String property=properties[i].getName();
			if(property.equalsIgnoreCase(str)){
				return property;
			}
		}
		return null;
	}
	public static String getSupperProperty(String str,Class<?> clazz){
		Field []properties=clazz.getDeclaredFields();
		Field []supperProperties=clazz.getSuperclass().getDeclaredFields();
		for(int i=0;i<properties.length;i++){
			for(int j=0;j<supperProperties.length;j++){
				if(properties[i].getName().equalsIgnoreCase(supperProperties[j].getName())){
					if(str.equalsIgnoreCase(properties[i].getName())){
						return str;
					}
				}
			}
		}
		
		for(int i=0;i<properties.length;i++){
			String property=properties[i].getName();
			if(property.equalsIgnoreCase(str)){
				return property;
			}
		}
	
		for(int i=0;i<supperProperties.length;i++){
			String property=supperProperties[i].getName();
			if(property.equalsIgnoreCase(str)){
				return property;
			}
		}
		return null;
	}
	public static Object[] getValuesByProperties(String[]properties,Object obj){
		Object []values=new Object[properties.length];
		for(int i=0;i<properties.length;i++){
			values[i]= callGetterMethod(properties[i],obj);
		}
		return values;
	}
	
	public Object getValueByProperty(String property,Object obj){
		return callGetterMethod(property,obj);
	}
	
	public static Map<String,Object> getSuperPropertiesAndValueMap(Object obj){
		Map<String,Object> map=getPropertiesMap(obj);
		Map superMap=getAllPropertiesMap(obj);
		for(String key:map.keySet()){
			if(superMap.containsKey(key)){
				superMap.remove(key);
			}
		}
		return superMap;
	}
	public static void main(String[]args){
	     User user=new User();
         user.setName("zs");
       //  System.out.println(getPropertiesMap(user));
	
	}
}
